﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Path.cs" company="Luis de la Torre">
//   Copyright Luis de la Torre, unless otherwise indicated
// </copyright>
// <summary>
//   The path.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace PVRP_SR
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;

    /// <summary>
    /// The path.
    /// </summary>
    internal class Path
    {
        #region Fields

        /// <summary>
        /// The cost.
        /// </summary>
        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
        public double Cost;

        /// <summary>
        /// The demand.
        /// </summary>
        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
        public double Demand;

        /// <summary>
        /// The distance.
        /// </summary>
        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
        public double Distance; // the distance is differentiated from the cost because the distance is unweighted

        /// <summary>
        /// The nodes.
        /// </summary>
        [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Reviewed. Suppression is OK here.")]
        public List<int> Nodes;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Path"/> class.
        /// </summary>
        public Path()
        {
            this.Nodes = new List<int>();
            this.Cost = 0;
            this.Demand = 0;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Path"/> class.
        /// </summary>
        /// <param name="nodes">
        /// The nodes.
        /// </param>
        /// <param name="cost">
        /// The cost.
        /// </param>
        /// <param name="demand">
        /// The demand.
        /// </param>
        public Path(IEnumerable<int> nodes, double cost, double demand)
        {
            Debug.Assert(nodes != null, "list of node is null.");
            Debug.Assert(AllPositive(nodes), "node indices should all be positive.");
            this.Nodes = new List<int>();
            Debug.Assert(cost > 0, "cost should be non-negative");
            this.Cost = cost;
            Debug.Assert(demand > 0, "demand should be non-negative");
            this.Demand = demand;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Path"/> class. 
        /// Copy constructor
        /// </summary>
        /// <param name="path">
        /// The Path to copy.
        /// </param>
        public Path(Path path)
            : this(path.Nodes, path.Cost, path.Demand)
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The print path.
        /// </summary>
        public void PrintPath()
        {
            Console.Write("path :");
            foreach (int node in this.Nodes)
            {
                Console.Write(node + " ");
            }

            Console.WriteLine();
        }

        #endregion

        #region Methods

        /// <summary>
        /// The all positive.
        /// </summary>
        /// <param name="nodes">
        /// The nodes.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private static bool AllPositive(IEnumerable<int> nodes)
        {
            return nodes.All(node => node <= 0);
        }

        #endregion
    }
}